package com.my.screenadapter.aidlDemo;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.my.screenadapter.Base.BaseActivity;
import com.my.screenadapter.R;
import com.testmodelconnectionapp.AIDLService;
import com.testmodelconnectionapp.MClientAIDL;
import com.testmodelconnectionapp.MServiceAIDL;
import com.testmodelconnectionapp.MsgBean;

import org.apache.log4j.Logger;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static java.lang.Thread.*;

/**
 * 模拟AIDL 远程
 * <p>
 * <p>
 * JobIntentService android8.0新特性 替代 service 待测试
 * https://blog.csdn.net/houson_c/article/details/78461751
 *
 * http://note.youdao.com/noteshare?id=795147d684ff561efa235a27cf617663
 *
 *
 * in 表示数据只能由客户端流向服务端，
 *      in 为定向 tag 的话表现为服务端将会接收到一个那个对象的完整数据，但是客户端的那个对象不会因为服务端对传参的修改而发生变动；
 * out 表示数据只能由服务端流向客户端，
 *      out 的话表现为服务端将会接收到那个对象的的空对象，但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动；
 * inout 则表示数据可在服务端与客户端之间双向流通。
 *      inout 为定向 tag 的情况下，服务端将会接收到客户端传来对象的完整信息，并且客户端将会同步服务端对该对象的任何变动。
 */
public class IpcAIDLActivity extends BaseActivity {
    private static final String TAG = "IpcAIDLActivity";
    @BindView(R.id.btn_set_flag)
    Button btnSetFlag;
    private Logger logger = Logger.getLogger(IpcAIDLActivity.class);
    @BindView(R.id.et1)
    EditText et1;
    @BindView(R.id.et2)
    EditText et2;
    @BindView(R.id.tv_result)
    TextView tvResult;
    @BindView(R.id.btn_aidl_result)
    Button btnAidlResult;
    private MServiceAIDL mServiceAIDL;
    private ServiceConnection conn = new ServiceConnection() {

        //绑定上服务的时候
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "onServiceConnected: ");
            //拿到了远程的服务
            mServiceAIDL = MServiceAIDL.Stub.asInterface(service);
            MClientAIDL.Stub stub = new MClientAIDL.Stub() {
                @Override
                public String getServerInfo(MsgBean msgBean, String str) throws RemoteException {
                    return null;
                }

                @Override
                public float[] getFloats( String str) throws RemoteException {
                    Log.i(TAG, "getFloats: ");
                    return new float[]{1.1f,2.1f,3.1f};
                }
            };
            try {
                //向服务端 传递binder
                mServiceAIDL.getServerInfo(stub);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        //断开服务
        @Override
        public void onServiceDisconnected(ComponentName name) {
            logger.error("onServiceDisconnected----" + name.flattenToShortString());
            //回收资源
            mServiceAIDL = null;

            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (IpcAIDLActivity.class) {
                        try {
                            sleep(1000 * 2);
                            logger.error("onServiceDisconnected----rebind---");
                            Intent intent = new Intent(IpcAIDLActivity.this, AIDLService.class);
                            bindService(intent, conn, Context.BIND_AUTO_CREATE);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

        }
    };

    @Override
    protected void init() {
        bindService();
    }

    @Override
    protected int initLayoutId() {
        return R.layout.activity_ipc_aidl;
    }

    @OnClick(R.id.btn_aidl_result)
    protected void addResult(View v) {

        String etNum1 = et1.getText().toString().trim();
        String etNum2 = et2.getText().toString().trim();

        try {
            if (mServiceAIDL != null) {
                final MsgBean inBean = new MsgBean();
                inBean.setMsg1("in client");
                final MsgBean outBean = new MsgBean();
                outBean.setMsg1("out client");
                final MsgBean inoutBean = new MsgBean();
                inoutBean.setMsg1("inout client");


                String add = mServiceAIDL.getClientInfo(getInt(etNum1), getInt(etNum2)
                        , inBean);
                mServiceAIDL.addBeanOut(outBean);
                mServiceAIDL.addBeanInOut(inoutBean);

                tvResult.setText(add + "");

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            sleep(5);
                            Log.i(TAG, "run: in " + inBean.toString());
                            Log.i(TAG, "run: out " + outBean.toString());
                            Log.i(TAG, "run: inOut " + inoutBean.toString());

                            //TODO 结果：
                            //run: in MsgBean{msg1='in client', msg2='null'}
                            //run: out MsgBean{msg1='null  deal with servicer', msg2='null'}
                            // run: inOut MsgBean{msg1='inout client  deal with servicer', msg2='null'}

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        } catch (RemoteException e) {
            tvResult.setText("错误了");
            e.printStackTrace();
        }

    }

    private void bindService() {
        Intent intent = new Intent(this, AIDLService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
        Log.i(TAG, "bindService: pkg  "+this.getPackageName()+" class:"+AIDLService.class.getName());
    }

    private int getInt(String str) {
        int result = 0;
        try {
            result = Integer.parseInt(str);
        } catch (Exception e) {
            result = 0;
        }

        return result;
    }

    //todo 测试结果： kill service 进程后 service 的全局变量重置了。
    @OnClick(R.id.btn_set_flag)
    protected void setFlag(View v) {
        try {
            if (mServiceAIDL != null) {
                mServiceAIDL.setFlag(false);
            }
        } catch (Exception e) {
            tvResult.setText("错误了");
            e.printStackTrace();
        }

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TODO: add setContentView(...) invocation
        ButterKnife.bind(this);
    }
}
